package com.audi.core.service;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Criterion;

import com.audi.core.common.Page;
import com.audi.core.dao.PropertyFilter;
import com.audi.core.dao.PropertyFilter.MatchType;


public interface BaseService<T, PK extends Serializable> {
	
public T save(T entity);
    
    public T update(T entity);

    public T saveOrUpdate(T entity);

    public T merge(T entity);
    
    public T getById(PK id);
    /**
     * 根据对象Id删除对象
     * @param id
     */
    public void deleteById(PK id);
    
    /**
     * 删除对象.
     * 
     * @param entity 对象必须是session中的对象或含id属性的transient对象.
     */
    public void delete( T entity);
    
    public List<T> getAll() ;
    
    /**
     * 分页查询
     */
    public Page<T> getAll(final Page<T> page) ;
    
    public Page<T> findPage(final Page<T> page, final String hql, final Object... values);  
    
    public Page<T> findPage(final Page<T> page, final String hql, final Map<String, ?> values) ;    
    
    public Page<T> findPage(final Page<T> page, final Criterion... criterions) ;

    public Page<T> findPage(final Page<T> page) ;
    
    public Page<T> findPage(int pageNo,int pageSize, final String hql, final Object... values); 
    
    public Page<T> findPage(int pageNo,int pageSize, final String hql, final Map<String, ?> values) ;   
    
    public Page<T> findPage(int pageNo,int pageSize, final Criterion... criterions) ;

    public Page<T> findPage(int pageNo,int pageSize) ;
    
    /**
     * 设置分页参数到Query对象,辅助函数.
     */
    public Query setPageParameter(final Query q, final Page<T> page) ;

    /**
     * 设置分页参数到Criteria对象,辅助函数.
     */
    public Criteria setPageParameter(final Criteria c, final Page<T> page) ;

    /**
     * 执行count查询获得本次Hql查询所能获得的对象总数.
     * 
     * 本函数只能自动处理简单的hql语句,复杂的hql查询请另行编写count语句查询.
     */
    public long countHqlResult(final String hql, final Object... values) ;

    /**
     * 执行count查询获得本次Hql查询所能获得的对象总数.
     * 
     * 本函数只能自动处理简单的hql语句,复杂的hql查询请另行编写count语句查询.
     */
    public long countHqlResult(final String hql, final Map<String, ?> values) ;

    /**
     * 执行count查询获得本次Criteria查询所能获得的对象总数.
     */
    
    public long countCriteriaResult(final Criteria c);

    /**
     * 属性过滤条件(PropertyFilter)查询函数
     * @param propertyName
     * @param value
     * @param matchType
     * @return
     */
    public List<T> findBy(final String propertyName, final Object value, final MatchType matchType);
    
    public List<T> find(List<PropertyFilter> filters) ;
    
    public Page<T> findPage(final Page<T> page, final List<PropertyFilter> filters) ;

    /**
     * 按属性条件列表创建Criterion数组,辅助函数.
     * 
     */
    public Criterion[] buildPropertyFilterCriterions(List<PropertyFilter> filters);
    
    /**
     * 按属性条件参数创建Criterion,辅助函数.
     */
    public Criterion buildCriterion(String propertyName,Object propertyValue, MatchType matchType);

    //public Criterion buildPropertyFilterCriterion(final String propertyName, final Object propertyValue,final MatchType matchType) ;
    /**
     * 判断属性是否唯一
     * @param propertyName
     * @param newValue
     * @param oldValue
     * @return
     */
    public boolean isPropertyUnique(final String propertyName, final Object newValue, final Object oldValue) ;

    /**
     * 原生sql支持
     * @param sql
     * @param cacheable
     * @return
     */
    public List executeList(String sql, boolean cacheable);
    
    /**
     * 原生sql支持带参数
     * @param sqlstr
     * @param params
     * @param cacheable
     * @return
     */
    public List executeListByCondition(String sqlstr, Object[] params, boolean cacheable);
    
    /**
     * 原生sql支持带参数及分页
     * @param begin
     * @param pageSize
     * @param sqlstr
     * @param params
     * @param cacheable
     * @return
     */
    public List executeListByCondition(int begin, int pageSize, String sqlstr, final Object[] params, boolean cacheable);
    
    /**
     * 
     * @param pageNo 页码
     * @param pageSize 页大小
     * @param hql ?号占位符hql
     * @param arr 参数
     * @return
     */
    public Page<T> findByProperty(int pageNo, int pageSize, String hql, Object[] arr);
    
    
    public T findUniqueBy(final String propertyName, final Object value);
    
    public void flush();
    
    /**
     * 按Criteria查询唯一对象.
     * 
     * @param criterions 数量可变的Criterion.
     */
    public T findUnique(final Criterion... criterions);
    
    
    /**
     * 执行HQL进行批量修改/删除操作.
     * 
     * @param values 数量可变的参数,按顺序绑定.
     * @return 更新记录数.
     */
    public int batchExecute(final String hql, final Object... values);
    
    
    /**
     * 执行HQL进行批量修改/删除操作.
     * 
     * @param values 命名参数,按名称绑定.
     * @return 更新记录数.
     */
    public int batchExecute(final String hql, final Map<String, ?> values);
    
    
    /**
     * 按HQL查询唯一对象.
     * 
     * @param values 数量可变的参数,按顺序绑定.
     */
    public <X> X findUnique(final String hql, final Object... values);
    
    //form S s where s.status=1
    public <X> X findUnique(String hql);
    
    /**
     * 按HQL查询唯一对象.
     * 
     * @param values 命名参数,按名称绑定.
     */
    public <X> X findUnique(final String hql, final Map<String, ?> values);
    
    
    /**
     * 按属性查找对象列表, 匹配方式为相等.
     */
    public List<T> findBy(final String propertyName, final Object value);
    
    /**
     *  获取全部对象, 支持按属性行序.
     */
    public List<T> getAll(String orderByProperty, boolean isAsc);
    
    /**
     * sql
     */
    public Page executePage(Page page, String sql, boolean cacheable);
    /**
     * sql
     */
    public Page executePage(int begin, int pageSize, String sqlstr, final Object[] params, boolean cacheable);
    /**
     * sql
     */
    public Page executePage(Page page, String sqlstr, final Object[] params, boolean cacheable);
    
    
    public <X> List<X> find(final String hql, final Object... values);

    /**
     * 按HQL查询对象列表.
     * 
     * @param values 命名参数,按名称绑定.
     */
    public <X> List<X> find(final String hql, final Map<String, ?> values);
    
	
}